<template>
  <div class="blog-content">
    <div v-if="isShowArticle" class="blog-content--article">
      <ArticleItem v-for="article of articles" :id="article.id" :key="article.id" :article="article" />
    </div>
    <div v-else class="blog-content--item">
      <h3 class="blog-item--title__unfind">很遗憾, 当前分类中没有文章</h3>
      <ElButton class="blog-item--btn" type="primary" @click="routeWrite">去写一篇吧</ElButton>
    </div>
  </div>
</template>

<!-- 
  1. 使用每个小卡片, 承载article.item
  2. 通过在create阶段请求articles内容, 使用v-for向下传递 article数据, 根据数据渲染html


  滚动条处理
  滚动到底部, 加载文章内容, 传递data参数, 获取页数, 然后push到articles中
  切换路由, 维持状态, 使用keepAlive(include指定组件维持状态(数据)) 使用actived生命周期在进入组件时, 重新设置滚动条位置


  1. 点击文章, 获取文章id, 进行前端路由跳转
  2. 跳转后, 在create阶段 发起请求, 获取article的内容, 然后根据数据渲染页面
-->
<script setup lang="ts">
import { ElNotification } from 'element-plus'
import QS from 'qs'
import { inject, watch, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'

import $http from '@/api/http'
import ArticleItem from '@/components/article/ArticleItem.vue'
import { $bus } from '@/unit/mitt'
let props = defineProps<{ loading: boolean; searchArticle: string }>()
let route = useRoute()
let router = useRouter()
let changeLoading = inject<Function>('changeLoading')
let articles = ref<any>([])
let page = ref<number>(1)
let size = ref<number>(2)
let isShowArticle = ref<boolean>(true)
let question = ref<string>('')
let isOver = ref<boolean>(false)
watch(
  () => props.loading,
  (newValue) => {
    if (newValue) {
      getArticles()
    }
  },
)
// eslint-disable-next-line vue/no-setup-props-destructure

onMounted(() => {
  // 每次从index跳转都会重新生成Home组件
  articles.value = []
  /*
      运行周期重叠, 当点击搜索时, 跳转真个页面, 然后修改字段, 修改完成字段后, 让子组件article进行监听, 如果发个声变化, 就修改内容
      重新获取文章内容, 但是问题是, 当数据发生更改时, 不能监听到内容的变换, 这是为什么, 只能是执行时间不正确,
      1. seach, 跳转页面, 然后mounted, 先子组件, 然后父组件, 在然后使用watch监听, 问题是 watch监听是组件跳转时就监听到, 那是后组件内病没哟渲染, 说明渲染时在后面渲染, 子组件渲染的内容获取不到, 而且之后获取的内容为空, 如果为空, 内容修改, 所有监听route, 是在组件后修, 当时组件并未万和城呢个渲染, 这之后再开始渲染, 如果渲染之后, 然后修改就等你解决这个问题, 这就是解决这个问题的方式, 渲染后修改通知内容
      那就是一开始就route, 然后初始值就位修改后的内容, 进行转接行不

      如何卡时间, 时间是什么执行的逻辑, 首先进行跳转, 两秒内没有加载完成, 无法监听到变化, 需要10s, 跳转, seach跳转, route跳转, mitt通知跳转, mitt通知组件未渲染, 首先需要进行跳转渲染, 然后再生成查询内容, 将q进行拼接, 一来就是可以获取内容

      
      总结: 在route跳转, 携带信息时, 目的地监听路由变化时另一套机制, 会先监听路由, 然后才渲染子组件, 以及本身的实例, 所以, 可以将通过传递下, 在子组件的onMounted直接使用, 不能使用watch监听route中变化的数据, 不然监听不到
    */
  if (props.searchArticle?.trim().length > 0) {
    searchArticles(props.searchArticle)
    return
  }
  // 第一次进来, 发现没有内容, 内容塌陷, 会触发两次loading
  getArticles()
})

function searchArticles(q) {
  question.value = q
  resetArticle()
  getArticles()
}

// 重置articles, 这些操作仅仅在不进行路由跳转的情况下使用
function resetArticle() {
  articles.value = []
  page.value = 1
}
function routeWrite() {
  let columnId = route.query.columns
  if (!columnId) {
    return false
  }
  router.push({ name: 'write', query: { columnId } })
}

// 如果this.q改变, 整个都要改变, q会变为undefined, 所以不能在里面改变this.q
function getQuery() {
  let queryData = { q: '' }
  let routeQuery = route.query
  queryData = Object.assign(queryData, routeQuery)
  // 这里的q需要使用全局, 方便后面加载时 使用q加载后面的page q需要太添加到query身上, 不需要做成相应式的尽量不做
  queryData.q = question.value || undefined
  return JSON.parse(JSON.stringify(queryData))
}
function getArticles({ isRest = false } = {}) {
  let data = { size: size.value, page: page.value, query: '' }
  let query = getQuery()
  if (Object.entries(query).length > 0) {
    data.query = QS.stringify(query)
  }

  $http({ type: 'articles', data })
    .then((result) => {
      let data = result.data
      if (isOver.value) {
        return
      }
      if (isRest === true) {
        page.value = 1
        articles.value = data.list
        return
      }
      // 数据是获取到的, 就看子组件的渲染出现问题
      if (data.list.length === 0) {
        console.log('没有文章了')
        isOver.value = true
      }
      if (data.total === 0) {
        isShowArticle.value = false
      }
      articles.value.push(...data.list)
      changeLoading()
      page.value++
    })
    .catch((err) => {
      console.log(err)
      ElNotification({
        title: '文章获取失败',
        message: err.message,
        type: 'error',
      })
    })
}
</script>
<style lang="stylus">
.blog-content {
  box-sizing: border-box;
  height: 100%;
  overflow: hidden;
}

.blog-item--title__unfind {
  margin-top: 80px;
  font-size: 28px;
}

.blog-item--btn.el-button {
  margin: 80px 0;
}
</style>
